package com.hnkywl.sts.service.htdygl;

import com.hnkywl.sts.dao.htdygl.HtdyDao;
import com.hnkywl.sts.dao.htdygl.HtwbDao;
import com.hnkywl.sts.dao.htdygl.HtysdyDao;
import com.hnkywl.sts.dao.htgl.CghtDao;
import com.hnkywl.sts.dao.htgl.HtDao;
import com.hnkywl.sts.dao.htgl.XshtDao;
import com.hnkywl.sts.entity.base.Sjzdz;
import com.hnkywl.sts.entity.htgl.*;
import com.hnkywl.sts.service.base.SjzdsyService;
import com.hnkywl.sts.service.htgl.HtService;
import com.hnkywl.sts.service.sys.YgService;
import com.hnkywl.sts.util.Constant;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: nianjunyan
 * Date: 13-4-11
 * Time: 上午11:44
 * To change this template use File | Settings | File Templates.
 */
@Service
public class DynaFormService {

    // 合同文本
    private HtwbDao htwbDao;

    private HtDao htDao;

    // 合同定义
    private HtdyDao htdyDao;

    //  数据字典索引
    private SjzdsyService sjzdsyService;

    // 合同文本service
    private HtwbService htwbService;

    // 合同元素定义
    private HtysdyDao htysdyDao;

    // 采购合同dao
    private CghtDao cghtDao;

    // 销售合同dao
    private XshtDao xshtDao;


    // 公司的合同模板
    public void saveHtmbData(Map<String, String> formDataMap, String htmbId, String htdyId) {
        // 更新
        updateHtmbData(formDataMap, Long.valueOf(htmbId), Long.valueOf(htdyId));
    }

    /**
     * 更新公司合同模板
     *
     * @param formDataMap
     * @param htmbId
     * @param htdyId
     */
    private void updateHtmbData(Map<String, String> formDataMap, Long htmbId, Long htdyId) {
        //Todo 拼接SQL语句进行更新
        List<Htys> htysList = this.htdyDao.get(htdyId).getHtysList();
        StringBuffer updateFiled = new StringBuffer();

        // 取字段和值进行拼接
        for (Htys htys : htysList) {
            if (StringUtils.isNotEmpty(formDataMap.get(htys.getYsid()))) {
                updateFiled.append(htys.getDybzd() + "=");
                updateFiled.append("'" + formDataMap.get(htys.getYsid()) + "'" + ",");
            }

        }

        String sqlHead = "update t_biz_htmb set " + updateFiled.substring(0, updateFiled.length() - 1) + "  where id=?";
        try {
            this.htwbDao.executeSQL(sqlHead, htmbId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 保存合同文本以及内容
    @Transactional
    public void saveFormData(Map<String, String> paramterMap, String htId, String htwbId, String htdyId) {

        // 根据合同文本id是否存在，判断是新增还是修改
        try {
            if (StringUtils.isEmpty(htwbId)) {
                addFormData(paramterMap, htId, htdyId);
            } else {
                updateFormData(Long.valueOf(htwbId), paramterMap);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    // 新增合同文本以及合同内容
    public void addFormData(Map<String, String> paramterMap, String htId, String htdyId) {
        // 新增合同文本
        Htwb htwb = addHtwb(htdyId);
        Ht ht = this.htDao.get(Long.valueOf(htId));
        ht.setHtwb(htwb);
        this.htDao.save(ht);

        // 新增合同内容
        addHtnr(htwb, paramterMap);
    }

    /**
     * 保存合同文本
     *
     * @param htdyid
     * @return
     */
    private Htwb addHtwb(String htdyid) {
        Htwb htwb = new Htwb();
        htwb.setHtdy(this.htdyDao.get(Long.valueOf(htdyid)));
        htwb.setZdr(YgService.getCurrentYg());
        htwb.setZdrq(new Date());
        htwb.setDateCreated(new Date());
        htwb.setCreateUser(YgService.getCurrentYg());
        htwb.setCreateOrgan(YgService.getCurrentYg().getZggs());
        htwb.setCreateOrgan(YgService.getCurrentYg().getZgjg());
        this.htwbDao.save(htwb);
        return htwb;
    }

    /**
     * 保存合同内容
     *
     * @param htwb
     * @param paramterMap
     */
    private void addHtnr(Htwb htwb, Map<String, String> paramterMap) {
        //Todo 拼接SQL语句进行塞入
        List<Htys> htysList = htwb.getHtdy().getHtysList();
        StringBuffer sbField = new StringBuffer();
        StringBuffer sbValue = new StringBuffer();
        sbField.append("(id,");
        sbValue.append("(" + htwb.getId() + ",");

        // 取字段和值进行拼接
        for (Htys htys : htysList) {
            sbField.append(htys.getDybzd() + ",");
            if (StringUtils.isEmpty(paramterMap.get(htys.getYsid()))) {
                sbValue.append("null" + ",");
            } else {
                sbValue.append("'" + paramterMap.get(htys.getYsid()) + "'" + ",");
            }

        }
        String sqlHead = "insert into t_biz_htnr" + sbField.substring(0, sbField.length() - 1) + ")" + " values " + sbValue.substring(0, sbValue.length() - 1) + ")";
        this.htwbDao.executeSQL(sqlHead);

    }


    /**
     * 更新合同文本以及内容
     *
     * @param htid
     * @param paramterMap
     */
    public void updateFormData(Long htid, Map<String, String> paramterMap) {
        // 更新合同文本
        Htwb htwb = updateHtwb(htid);

        // 更新合同内容
        updateHtnr(htwb, paramterMap);
    }

    /**
     * 更新合同文本
     *
     * @param htwbId
     * @return
     */
    private Htwb updateHtwb(Long htwbId) {
        Htwb htwb = htwbDao.get(Long.valueOf(htwbId));
        htwb.setZdr(YgService.getCurrentYg());
        htwb.setZdrq(new Date());
        htwb.setLastUpdated(new Date());
        htwbDao.save(htwb);
        return htwb;
    }


    /**
     * 更新合同内容
     *
     * @param htwb
     * @param paramterMap
     */
    private void updateHtnr(Htwb htwb, Map<String, String> paramterMap) {
        //Todo 拼接SQL语句进行更新
        List<Htys> htysList = htwb.getHtdy().getHtysList();
        StringBuffer updateFiled = new StringBuffer();

        // 取字段和值进行拼接
        for (Htys htys : htysList) {
            if (StringUtils.isNotEmpty(paramterMap.get(htys.getYsid()))) {
                updateFiled.append(htys.getDybzd() + "=");
                updateFiled.append("'" + paramterMap.get(htys.getYsid()) + "'" + ",");
            }

        }
        String sqlHead = "update t_biz_htnr set " + updateFiled.substring(0, updateFiled.length() - 1) + "  where id=" + htwb.getId();
        this.htwbDao.executeSQL(sqlHead);
    }


    /**
     * 得到合同内容 （一般新建时使用）
     *
     * @param htdy 合同定义
     * @return
     */
    public String getFormHtml(Htdy htdy, String htmbId) {
        // 查询是否已经定义了部门合同模板
        Map<String, String> formMbData = null;
        if (StringUtils.isNotEmpty(htmbId)) {
            formMbData = this.getFormMbData(htdy.getId(), htmbId);
            // 判断是否有数据
            if (formMbData.size() == 0) {
                formMbData = null;
            }
        }
        return this.getFormHtml(htdy, null, null, formMbData);
    }

    /**
     * 得到合同内容 （一般修改时使用）
     *
     * @param htwb 合同文本
     * @return
     */
    public String getFormHtml(Htwb htwb) {
        // 查询是否已经保存了合同内容
        Map<String, String> formData = this.getFormData(htwb);
        return this.getFormHtml(htwb.getHtdy(), htwb.getId().toString(), formData, null);
    }

    /**
     * 得到合同内容
     *
     * @param htdy     合同定义
     * @param formData 合同关联值
     * @return
     */
    public String getFormHtml(Htdy htdy, String htwbId, Map<String, String> formData, Map<String, String> formMbData) {
        return fillFormHtml(htdy.getHtml(), htdy.getHtysList(), htwbId, formData, formMbData);
    }

    /**
     * 填充html中的值
     *
     * @param html
     * @param elementConfigs 相关元素配置
     * @param formData       合同关联值
     * @return
     */
    private String fillFormHtml(String html, List<Htys> elementConfigs, String htwbId, Map<String, String> formData, Map<String, String> formMbData) {
        //构件jsoup的document
        Document document = Jsoup.parse(html);
        renderElements(document, elementConfigs, htwbId, formData, formMbData);
        return document.outerHtml();
    }

    /**
     * 渲染元素并填充值
     *
     * @param document
     * @param elementConfigs 元素配置
     * @param formData       值
     */
    private void renderElements(Document document, List<Htys> elementConfigs, String htwbId, Map<String, String> formData, Map<String, String> formMbData) {
        // 输出合同定义id,合同定义id
        if (null != elementConfigs && elementConfigs.size() > 0) {
            renderHiddenId(elementConfigs.get(0), htwbId, document);
        }

        // 输出html
        for (Htys elementConfig : elementConfigs) {
            renderElement(elementConfig, document, formData, formMbData);
        }
    }

    /**
     * 渲染元素并填充
     *
     * @param elementConfig
     * @param document
     * @param formData
     */
    private void renderElement(Htys elementConfig, Document document, Map<String, String> formData, Map<String, String> formMbData) {
        Element element = getElementByName(document, elementConfig.getYsid());
        if (element == null) return;

        //根据类型进行修改
        /**
         *elementConfig.getYxlx()  选项类型（1、纯文本 2、数据字典 3、数据集 4、日期 5、固定下拉）
         */
        if (null != elementConfig.getYxlx() && elementConfig.getYxlx() > 0) {
            switch (elementConfig.getYxlx()) {
                case 1:
                    setTextValue(element, elementConfig, formData, formMbData);
                    return;
                case 2:
                    refactorSjzdElement(element, elementConfig, formData, formMbData);
                    return;
                case 3:
                    refactorSjjElement(element, elementConfig, formData, formMbData);
                    return;
                case 4:
                    refactorDateElement(element, elementConfig, formData, formMbData);
                    return;
                case 5:
                    refactorGdxlElement(element, elementConfig, formData, formMbData);
                    return;
            }
        }

    }

    /**
     * 输出隐藏的合同定义id
     *
     * @param elementConfig
     * @param document
     */
    private void renderHiddenId(Htys elementConfig, String htwbId, Document document) {
        Elements element = document.getElementsByAttributeValue("name", elementConfig.getYsid());
        // 赋值，隐藏的合同定义id
        Element hInput = document.createElement("input");
        hInput.attr("type", "hidden");
        hInput.attr("id", "htdy_id");
        hInput.attr("value", elementConfig.getHtdy().getId().toString());

        if (null != element && element.size() > 0) {
            element.get(0).after(hInput);
        }

        // 赋值，隐藏合同id，永远判断合同文本是新增还是修改
        Element htInput = document.createElement("input");
        htInput.attr("type", "hidden");
        htInput.attr("id", "htwb_id");
        if (null != htwbId) {
            htInput.attr("value", htwbId);
        }
        if (null != element && element.size() > 0) {
            element.get(0).after(htInput);
        }
    }

    /**
     * 加载控件的值 ,文本
     *
     * @param element
     * @param elementConfig
     * @param formData
     */
    private void setTextValue(Element element, Htys elementConfig, Map<String, String> formData, Map<String, String> formMbData) {

        // 判断是否可以修改
        if (StringUtils.isNotEmpty(elementConfig.getIsread()) && elementConfig.getIsread().equals("0")) {
            element.attr("readonly", "true");
        }

        // 加载长度限制
        if (null != elementConfig.getWbcd() && elementConfig.getWbcd() > 0) {
            element.attr("maxlength", elementConfig.getWbcd().toString());
        }

        // 默认值
        if (formData == null) {

            // 判断公司是否已经定义了模板
            if ((formMbData == null) || (StringUtils.isNotEmpty(elementConfig.getIsread()) && elementConfig.getIsread().equals("0"))) {
                if (StringUtils.isNotEmpty(elementConfig.getMrz())) {
                    if (elementConfig.getMrz().toLowerCase().equals(Constant.CURRENT_DATE)) {
                        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        element.val(df.format(new Date()));
                    } else {
                        element.val(elementConfig.getMrz());
                    }
                }
            } else {
                for (String key : formMbData.keySet()) {
                    if (key.equals(elementConfig.getYsid())) {
                        try {
                            element.val(this.htwbService.getValue(formMbData.get(key)));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            return;
        }

        //传入值
        for (String key : formData.keySet()) {
            if (key.equals(elementConfig.getYsid())) {
                try {
                    element.val(this.htwbService.getValue(formData.get(key)));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 数据字典
     *
     * @param element
     * @param elementConfig
     * @param formData
     */
    private void refactorSjzdElement(Element element, Htys elementConfig, Map<String, String> formData, Map<String, String> formMbData) {

        List<String> dropDownList = new ArrayList<String>();
        if (StringUtils.isNotEmpty(elementConfig.getQz())) {
            for (Sjzdz sjzdz : sjzdsyService.findSjzdsy(elementConfig.getQz())) {
                dropDownList.add(sjzdz.getZ());
            }

            // 获取option
            renderSelect(dropDownList, elementConfig, element, formData, formMbData);
        }
    }

    /**
     * 数据集
     *
     * @param element
     * @param elementConfig
     * @param formData
     */
    private void refactorSjjElement(Element element, Htys elementConfig, Map<String, String> formData, Map<String, String> formMbData) {

        List<String> dropDownList = new ArrayList<String>();
        if (StringUtils.isNotEmpty(elementConfig.getQz())) {
            String inputSql = elementConfig.getQz();
            try {
                List listDate = this.htysdyDao.findBySQL(inputSql);
                for (int i = 0; i < listDate.size(); i++) {
                    dropDownList.add(listDate.get(i).toString());
                }
            } catch (Exception e) {
            }
            // 获取select
            renderSelect(dropDownList, elementConfig, element, formData, formMbData);
        }
    }

    /**
     * 加载时间控件
     *
     * @param element
     * @param elementConfig
     * @param formData
     */
    private void refactorDateElement(Element element, Htys elementConfig, Map<String, String> formData, Map<String, String> formMbData) {

        if (element != null && element.select("input[name]").size() > 0) {
            if (element.select("input[name]").attr("name").equals(elementConfig.getYsid())) {
                element.attr("onfocus", "WdatePicker()").attr("class", "Wdate");
                if (null != formData) {
                    for (String key : formData.keySet()) {
                        if (key.equals(elementConfig.getYsid())) {
                            try {
                                element.attr("value", this.htwbService.getValue(formData.get(key)));
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }

                } else if (null != formMbData) {
                    if (StringUtils.isNotEmpty(elementConfig.getIsread()) && elementConfig.getIsread().equals("0")) {
                        if (elementConfig.getMrz().toLowerCase().equals(Constant.CURRENT_DATE)) {
                            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            element.attr("value", df.format(new Date()));
                        } else {
                            element.attr("value", elementConfig.getMrz());
                        }
                    } else {
                        for (String key : formMbData.keySet()) {
                            if (key.equals(elementConfig.getYsid())) {
                                try {
                                    element.attr("value", this.htwbService.getValue(formMbData.get(key)));
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                } else if (StringUtils.isNotEmpty(elementConfig.getMrz())) {
                    if (elementConfig.getMrz().toLowerCase().equals(Constant.CURRENT_DATE)) {
                        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        element.attr("value", df.format(new Date()));
                    } else {
                        element.attr("value", elementConfig.getMrz());
                    }
                }
            }
        }
    }

    /**
     * 固定下拉
     *
     * @param element
     * @param elementConfig
     * @param formData
     */
    private void refactorGdxlElement(Element element, Htys elementConfig, Map<String, String> formData, Map<String, String> formMbData) {

        List<String> dropDownList = new ArrayList<String>();

        if (StringUtils.isNotEmpty(elementConfig.getQz())) {
            String[] gdxlStr = elementConfig.getQz().split(",");
            for (int i = 0; i < gdxlStr.length; i++) {
                dropDownList.add(gdxlStr[i]);
            }
        }
        // 获取select
        renderSelect(dropDownList, elementConfig, element, formData, formMbData);
    }

    /**
     * 获取select
     *
     * @param dropDownList
     * @param elementConfig
     * @param element
     * @param formData
     */
    private void renderSelect(List<String> dropDownList, Htys elementConfig, Element element, Map<String, String> formData, Map<String, String> formMbData) {

        // 判断是否已经有对应的值
        String initValue = "";
        if (null != formData) {
            for (String key : formData.keySet()) {
                if (key.equals(elementConfig.getYsid())) {
                    try {
                        initValue = this.htwbService.getValue(formData.get(key));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        } else if (null != formMbData) {
            if (StringUtils.isNotEmpty(elementConfig.getIsread()) && elementConfig.getIsread().equals("0")) {
                if (StringUtils.isNotEmpty(elementConfig.getMrz())) {
                    initValue = elementConfig.getMrz();
                }
            } else {
                for (String key : formMbData.keySet()) {
                    if (key.equals(elementConfig.getYsid())) {
                        try {
                            initValue = this.htwbService.getValue(formMbData.get(key));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        } else {
            if (StringUtils.isNotEmpty(elementConfig.getMrz())) {
                initValue = elementConfig.getMrz();
            }
        }

        // 下拉框
        StringBuffer sbSelect = new StringBuffer();

        // 输入框
        StringBuffer sbInput = new StringBuffer();
        // 下拉框值
        StringBuffer sbOption = new StringBuffer();

        // 输入框值绑定到下拉框中
        boolean isExist = false;
        for (String dropDown : dropDownList) {
            if (dropDown.equals(initValue)) {
                isExist = true;
                break;
            }
        }
        if (!isExist) {
            sbOption.append("<option value='" + initValue + "' >" + initValue + "</option>");
        }

        // 绑定select下拉值
        for (String dropDown : dropDownList) {
            sbOption.append("<option value='" + dropDown + "' >" + dropDown + "</option>");
        }
        // 判断是否可以修改
        if (StringUtils.isNotEmpty(elementConfig.getIsread()) && elementConfig.getIsread().equals("0")) {
            sbSelect.append("<select disabled=\"disabled\" style=\"width:98.5%;height:20px;margin-left:-100px;border-style:none;color:#485f71;\" onchange=\"$('#" + elementConfig.getYsid() + "').val($(this).val());\" >" +
                    sbOption + "</select>");

            sbInput.append("<input readonly=\"true\" id='" + elementConfig.getYsid() + "'name=" + elementConfig.getYsid() + " style=\"width:95.9%;border-style:none;position:absolute;left:0px;\" " +
                    "value=" + initValue + ">");
        } else {
            sbSelect.append("<select  style=\"width:98.5%;height:20px;margin-left:-100px;border-style:none;color:#485f71;\" onclick=\"$('#" + elementConfig.getYsid() + "').val($(this).val());\" >" +
                    sbOption + "</select>");

            sbInput.append("<input  id='" + elementConfig.getYsid() + "'name=" + elementConfig.getYsid() + " style=\"width:95.9%;border-style:none;position:absolute;left:0px;\" " +
                    "value=" + initValue + ">");
        }

        element.tagName("div").attr("style", "position:relative;");
        element.html("<span style=\"margin-left:100px;width:18px;overflow:hidden;\">" +
                sbSelect + "</span>" + sbInput);

    }

    /**
     * 获取名称
     *
     * @param document
     * @param ysid
     * @return
     */
    private Element getElementByName(Document document, String ysid) {
        Elements elements = document.select("[name=" + ysid + "]");
        return elements.size() > 0 ? elements.get(0) : null;
    }

    /**
     * 取得公司合同模板内容和值的对应map
     *
     * @param htdyId
     * @return
     */
    private Map<String, String> getFormMbData(Long htdyId, String htmbId) {
        HashMap<String, String> hashMap = new HashMap<String, String>();
        // 查询所有的元素
        List<Htys> htysList = this.htdyDao.get(htdyId).getHtysList();
        for (Htys htys : htysList) {
            String sql = "select " + htys.getDybzd() + "  from t_biz_htmb where id=? ";
            List<String> valueList = this.htwbDao.findBySQL(sql, htmbId);

            if (null != valueList && valueList.size() > 0 && null != valueList.get(0)) {
                hashMap.put(htys.getYsid(), valueList.get(0).toString());
            }

        }
        return hashMap;
    }

    /**
     * 取得合同内容和值的对应map
     *
     * @param htwb
     * @return
     */
    private Map<String, String> getFormData(Htwb htwb) {
        HashMap<String, String> hashMap = new HashMap<String, String>();
        // 查询所有的元素
        List<Htys> htysList = htwb.getHtdy().getHtysList();
        for (Htys htys : htysList) {
            String sql = "select " + htys.getDybzd() + "  from t_biz_htnr where id=?";
            List<String> valueList = this.htwbDao.findBySQL(sql, htwb.getId());

            if (null != valueList && valueList.size() > 0 && null != valueList.get(0)) {
                hashMap.put(htys.getYsid(), valueList.get(0).toString());
            }

        }
        return hashMap;
    }

    //html得到保存时的html
    public String getHtml() {
        return "";
    }

    @Autowired
    public void setSjzdsyService(SjzdsyService sjzdsyService) {
        this.sjzdsyService = sjzdsyService;
    }

    @Autowired
    public void setHtysdyDao(HtysdyDao htysdyDao) {
        this.htysdyDao = htysdyDao;
    }

    @Autowired
    public void setHtwbDao(HtwbDao htwbDao) {
        this.htwbDao = htwbDao;
    }

    @Autowired
    public void setHtdyDao(HtdyDao htdyDao) {
        this.htdyDao = htdyDao;
    }

    @Autowired
    public void setHtwbService(HtwbService htwbService) {
        this.htwbService = htwbService;
    }

    @Autowired
    public void setCghtDao(CghtDao cghtDao) {
        this.cghtDao = cghtDao;
    }

    @Autowired
    public void setXshtDao(XshtDao xshtDao) {
        this.xshtDao = xshtDao;
    }

    @Autowired
    public void setHtDao(HtDao htDao) {
        this.htDao = htDao;
    }
}
